package oboe.util;
import flash.events.Event;
import flash.events.IEventDispatcher;
import oboe.core.SigSlot;
import oboe.core.ISigSlot;

/**
 * ...
 * @author Felipe Manga
 */

enum SigType
{
	SIGNAL_UP( name:String, param:Array<Dynamic> );
	SIGNAL_DOWN( name:String, param:Array<Dynamic> );
	SIGNAL( name:String, param:Array<Dynamic> );
	BROADCAST_SIGNAL( name:String, param:Array<Dynamic> );
	SHORT_SIGNAL( name:String, param:Array<Dynamic> );
	MESSAGE( name:String, param:Array<Dynamic> );
}

class Prototype 
{

	public static function addCallback( THIS:ISigSlot, target:IEventDispatcher, event:String, sig:SigType )
	{
		target.addEventListener( event, 
			function ( e:Event ):Void
			{ 
				var ss:SigSlot = Reflect.field( THIS, "sigslot" );
				switch( sig )
				{
				case SIGNAL_UP( name, param ): ss.signalUp( name, param );
				case SIGNAL_DOWN( name, param ): ss.signalDown( name, param );
				case SIGNAL( name, param ): ss.signal( name, param );
				case BROADCAST_SIGNAL( name, param ): ss.broadcastSignal( name, param );
				case SHORT_SIGNAL( name, param ): ss.shortSignal( name, param );
				case MESSAGE( name, param ): ss.message( name, param );
				}
			}
		);
	}
	
	public static function addMessage( THIS:ISigSlot, target:Dynamic, event:String, signame:String, args:Array<Dynamic> )
	{
		var ss:SigSlot = Reflect.field( THIS, "sigslot" );
		var ret = function ( e:Event ):Void
		{
			ss.message( signame, args );
		}
		target.addEventListener( 
			event,
			ret
		);
		return ret;
	}

	public static function addSignalDown( THIS:ISigSlot, target:Dynamic, event:String, signame:String, args:Array<Dynamic> ):Void
	{
		var ss:SigSlot = Reflect.field( THIS, "sigslot" );
		target.addEventListener( 
			event,
			function ( e:Event ):Void
			{
				ss.signalDown( signame, args );
			}
		);
	}
	
	public static function addSignalUp( THIS:ISigSlot, target:Dynamic, event:String, signame:String, args:Array<Dynamic> ):Void
	{
		var ss:SigSlot = Reflect.field( THIS, "sigslot" );
		target.addEventListener( 
			event,
			function ( e:Event ):Void
			{
				ss.signalUp( signame, args );
			}
		);
	}
	
	public static function addShortSignal( THIS:ISigSlot, target:Dynamic, event:String, signame:String, args:Array<Dynamic> ):Void
	{
		var ss:SigSlot = Reflect.field( THIS, "sigslot" );
		target.addEventListener( 
			event,
			function ( e:Event ):Void
			{
				ss.shortSignal( signame, args );
			}
		);
	}
	
	public static function addSignal( THIS:ISigSlot, target:Dynamic, event:String, signame:String, args:Array<Dynamic> ):Void
	{
		var ss:SigSlot = Reflect.field( THIS, "sigslot" );
		target.addEventListener( 
			event,
			function ( e:Event ):Void
			{
				ss.signal( signame, args );
			}
		);
	}

	public static function addBroadcastSignal( THIS:ISigSlot, target:Dynamic, event:String, signame:String, args:Array<Dynamic> ):Void
	{
		var ss:SigSlot = Reflect.field( THIS, "sigslot" );
		target.addEventListener( 
			event,
			function ( e:Event ):Void
			{
				ss.broadcastSignal( signame, args );
			}
		);
	}
}